package com.sxintelbox

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.hardware.usb.UsbDevice
import android.os.Handler
import android.util.Log
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.UiThreadUtil
import com.herohan.uvcapp.CameraHelper
import com.herohan.uvcapp.ICameraHelper
import com.herohan.uvcapp.IImageCapture
import com.herohan.uvcapp.IImageCapture.OnImageCaptureCallback
import com.hikvision.netsdk.HCNetSDK
import com.hikvision.netsdk.INT_PTR
import com.hikvision.netsdk.NET_DVR_JPEGPARA
import com.serenegiant.usb.Size
import com.sxintelbox.Control.DevManageGuider
import com.sxintelbox.Control.SDKGuider
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import javax.annotation.Nullable


class HKVisionDeviceModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
    override fun getName(): String {
        return "HKVisionDeviceModule"
    }

    private var cameraHelper: ICameraHelper? = null

    @ReactMethod
    fun login(devName:String, ip:String, port:String, userName:String, password: String, promise: Promise) {
        // clicked add button

        // 在非UI线程调用SDK
        runBlocking {
            launch {
                val deviceItem: DevManageGuider.DeviceItem = SDKGuider.g_sdkGuider.m_comDMGuider.DeviceItem()
                deviceItem.m_szDevName = devName
                deviceItem.m_struNetInfo = SDKGuider.g_sdkGuider.m_comDMGuider.DevNetInfo(
                    ip,
                    port,
                    userName,
                    password
                );
                if(SDKGuider.g_sdkGuider.m_comDMGuider.login_v40_jna(deviceItem.m_szDevName, deviceItem.m_struNetInfo)){
                    UiThreadUtil.runOnUiThread(Runnable {
                        promise.resolve(true);
                    })
                }
                else {
                    val reason: Int = SDKGuider.g_sdkGuider.GetLastError_jni();
                    // int 转为String
                    UiThreadUtil.runOnUiThread(Runnable {
                        promise.reject(reason.toString());
                    })
                }
            }
        }
    }

    @ReactMethod
    fun logout() {
        SDKGuider.g_sdkGuider.m_comDMGuider.login_v40_jna_with_index(0)
    }

    @ReactMethod
    fun snap(path: String, picQuality:Int, picSize: Int, bufferSize: Int,  promise: Promise) {
        // 设置抓拍参数
        val strJpeg = NET_DVR_JPEGPARA()
        strJpeg.wPicQuality = picQuality
        strJpeg.wPicSize = picSize
        val iBufferSize = bufferSize
        val sbuffer = ByteArray(iBufferSize)
        val bytesRerned = INT_PTR()
        if (SDKGuider.g_sdkGuider.m_comDMGuider.devList.size == 0) {
            promise.reject("未登录");
            return;
        }
        val flag: Boolean = HCNetSDK.getInstance()
            .NET_DVR_CaptureJPEGPicture_NEW(SDKGuider.g_sdkGuider.m_comDMGuider.devList.get(0).m_lUserID, 1, strJpeg, sbuffer, iBufferSize, bytesRerned)
        if (flag) {
            val bitmap = BitmapFactory.decodeByteArray(sbuffer, 0, sbuffer.size)
            // android保存bitmap到path
            try {
                val fos = FileOutputStream(path)
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos) // 使用JPEG格式，质量设置为100%
                fos.flush()
                fos.close()
                promise.resolve(path);
            } catch (e: IOException) {
                e.printStackTrace()
                promise.resolve(e.localizedMessage);
            }
        }
        else {
            promise.reject(HCNetSDK.getInstance().NET_DVR_GetLastError().toString());
        }
    }

    fun takePicture(path:String, cameraHelper: ICameraHelper,  promise: Promise) {
        cameraHelper.imageCaptureConfig.setCaptureMode(IImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY);
        cameraHelper.imageCaptureConfig.setCaptureStrategy(IImageCapture.CAPTURE_STRATEGY_IMAGE_READER);
        var file = File(path);
        val options =
            IImageCapture.OutputFileOptions.Builder(file).build()
        cameraHelper.takePicture(options, object : OnImageCaptureCallback {
            override fun onImageSaved(outputFileResults: IImageCapture.OutputFileResults) {
                promise.resolve(path);
                cameraHelper.release();
            }

            override fun onError(
                imageCaptureError: Int,
                message: String,
                @Nullable cause: Throwable?
            ) {
                promise.reject(cause);
            }
        })
    }

    @ReactMethod
    fun snapUVC(path: String, picQuality:Int, picSize: Int, bufferSize: Int,  promise: Promise) {
        var cameraHelper:ICameraHelper = CameraHelper()
        this.cameraHelper = cameraHelper;
        cameraHelper.setStateCallback(object : ICameraHelper.StateCallback {
            override fun onAttach(device: UsbDevice) {
                cameraHelper.selectDevice(device);
            }

            override fun onDeviceOpen(device: UsbDevice, isFirstOpen: Boolean) {
                cameraHelper.openCamera()
            }

            override fun onCameraOpen(device: UsbDevice) {
                cameraHelper.startPreview()
                // 2秒后执行takePicture
                takePicture(path, cameraHelper, promise)
            }

            override fun onCameraClose(device: UsbDevice) {

            }

            override fun onDeviceClose(device: UsbDevice) {
            }

            override fun onDetach(device: UsbDevice) {
                
            }

            override fun onCancel(device: UsbDevice) {
            }
        });
    }
}